import {Injectable} from '@angular/core';

enum ThemeType {
  dark = 'dark',
  default = 'default'
}

@Injectable({
  providedIn: 'root'
})
export class ThemeService {
  currentTheme = ThemeType.default
  light = true

  constructor() {
  }

  isLight(): boolean {
    return this.light
  }

  toggleTheme(): Promise<Event> {
    this.currentTheme = ThemeService.reverseTheme(this.currentTheme);
    this.light = !this.light
    return this.loadTheme(false);
  }

  loadTheme(firstLoad: boolean = true): Promise<Event> {
    const theme = this.currentTheme
    if (firstLoad) {
      document.documentElement.classList.add(theme)
    }
    return new Promise<Event>((resolve, reject) => {
      this.loadCSS(`${theme}.css`, theme).then(
        (e) => {
          if (!firstLoad) {
            document.documentElement.classList.add(theme)
          }
          ThemeService.removeUnusedTheme(ThemeService.reverseTheme(theme))
          resolve(e)
        },
        (e) => reject(e)
      )
    })
  }

  private loadCSS(href: string, id: string): Promise<Event> {
    return new Promise<Event>((resolve, reject) => {
      const style = document.createElement('link')
      style.rel = 'stylesheet'
      style.href = href
      style.id = id
      style.onload = resolve
      style.onerror = reject
      document.head.append(style)
    })
  }

  private static reverseTheme(theme: string): ThemeType {
    return theme === ThemeType.dark ? ThemeType.default : ThemeType.dark
  }

  private static removeUnusedTheme(theme: ThemeType): void {
    document.documentElement.classList.remove(theme)
    const removedThemeStyle = document.getElementById(theme)
    if (removedThemeStyle) {
      document.head.removeChild(removedThemeStyle)
    }
  }
}
